<template>
  <div class="home">
    <!--    <img alt="Vue logo" src="../assets/logo.png">-->
    <title>multicastAlgorithm</title>
    <h1>multicastAlgorithm</h1>
    <div>
      <el-row>
        <el-button type="primary" plain @click="centerDialogVisible = true;alType=1">NCA算法</el-button>
        <el-button type="primary" plain @click="centerDialogVisible = true;alType=2">CA算法</el-button>
      </el-row>
      <!--      echars图片显示-->
      <!--      <div style="display: flex;flex-direction: row;">-->
      <el-row type="flex">
        <el-card class="box-card-left">
          <span>网络拓扑图</span>
          <div id="mynetwork">
          </div>
        </el-card>
        <!--          显示结果图-->
        <el-card class="box-card-right">
          <span>网络最优路径</span>
          <div id="mynetworkRoute">
          </div>
        </el-card>
      </el-row>
      <el-row>
        <el-card class="table-button">
          <span>结果统计表</span>
          <el-table
              :data="tableData"
              style="width: 100%"
          >
            <el-table-column
                prop="num"
                label="次数"
                width="180">
            </el-table-column>
            <el-table-column
                prop="alType"
                label="algorithm"
                width="180">
            </el-table-column>
            <el-table-column
                prop="weightsum"
                label="weightsum"
                width="180">
            </el-table-column>
            <el-table-column
                prop="deployServer"
                label="deployServer">
            </el-table-column>
            <el-table-column
                prop="deployNode"
                label="deployNode">
            </el-table-column>
          </el-table>
        </el-card>
      </el-row>
      <el-dialog
          title="设置模拟参数"
          :visible.sync="centerDialogVisible"
          width="60%"

          center>
        <el-form ref="form" :model="form" label-width="70%" v-loading="loading" >
          <el-row>
            <el-col :span="11">
              <el-form-item label="nodeNum：" :required="true">
                <el-input v-model="form.nodeNum"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="11">
              <el-form-item label="maxBk：" :required="true">
                <el-input v-model="form.maxBk"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="11">
              <el-form-item label="functionNum：" :required="true">
                <el-input v-model="form.functionNum"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="11">
              <el-form-item label="maxDeploymentCost：" :required="true">
                <el-input v-model="form.maxDeployMent"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="11">
              <el-form-item label="parallelNum：" :required="true">
                <el-input v-model="form.parallelNum"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="11">
              <el-form-item label="destinationVRadio：" :required="true">
                <el-input v-model="form.destinationVRadio"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="11">
              <el-form-item label="maxEdgeCost：" :required="true">
                <el-input v-model="form.maxEdgeCost"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="11">
              <el-form-item label="parallelPosition：" :required="true">
                <el-input v-model="form.parallelPostion"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="centerDialogVisible = false;loading=false;">取 消</el-button>
          <el-button type="primary" @click="checkForm">确 定</el-button>
        </span>
      </el-dialog>
    </div>
  </div>

</template>

<script>
// @ is an alias to /src
// 导入vis 以及需要
import {GetBMPE, GetCA} from '../utils/api'
import * as vis from 'vis';
import * as echarts from 'echarts/core';
import {GridComponent} from 'echarts/components';
import {BarChart} from 'echarts/charts';
import {CanvasRenderer} from 'echarts/renderers';

// 这里使用页面全局，因为需要动态添加点和边
let networkNodes;
let networkEdges;
let netResultNodes;
let netResultEdges;

const MAX = 999999;
export default {
  name: 'Home',

  data() {
    return {
      name: "网络拓扑图",
      alType: 1, // 算法种类，默认1
      centerDialogVisible: false, // 显示对话框
      loading:false,
      form: {
        nodeNum: 50,
        maxEdgeCost: 10,
        functionNum: 5,
        maxBk: 5,
        maxDeployMent: 5,
        parallelNum: 3,
        destinationVRadio: 0.1,
        parallelPostion: 0
      },
      tableData: [],
      manipulation: {
        enabled: true, //该属性表示可以编辑，出现编辑操作按钮
        addNode: true,
        addEdge: true,
        // editNode: undefined,
        editEdge: true,
        deleteNode: true,
        deleteEdge: true,
      },
      interaction: {
        dragNodes: true, //是否能拖动节点
        dragView: true, //是否能拖动画布
        hover: true, //鼠标移过后加粗该节点和连接线
        multiselect: true, //按 ctrl 多选
        selectable: true, //是否可以点击选择
        selectConnectedEdges: true, //选择节点后是否显示连接线
        hoverConnectedEdges: true, //鼠标滑动节点后是否显示连接线
        zoomView: true, //是否能缩放画布
      },
      //---------echarts相关------------------------/
      // echart图表x轴显示
      mycharts: null,
      xAxis: {
        type: 'category',
        data: ['time', 'money']
      },
      series: [
        {
          data: [120, 200],  // 显示值
          type: 'bar',
          showBackground: true,
          // 设置背景颜色
          backgroundStyle: {
            color: 'rgba(180, 180, 180, 0.2)'
          }
        }
      ]
    };
  },
  mounted() {
    // 页面加载
  },
  methods: {

    checkForm() {
      // 首先检查所有参数
      let formData = this.form;
      if (formData.nodeNum == null || formData.nodeNum <= 30 || formData.nodeNum > 2000) {
        this.$message.error('请正确填写nodeNum,范围[30,2000]');
        return;
      }
      if (formData.maxEdgeCost == null || formData.maxEdgeCost <= 0 || formData.maxEdgeCost > 2000) {
        this.$message.error('请正确填写maxEdgeCost，范围[1,2000]');
        return;
      }
      if (formData.functionNum == null || formData.functionNum <= 0 || formData.functionNum > 2000) {
        this.$message.error('请正确填写functionNum，范围[1,2000]');
        return;
      }
      if (formData.maxBk == null || formData.maxBk <= 0 || formData.maxBk > 2000) {
        this.$message.error('请正确填写maxBk，范围[1,2000]');
        return;
      }
      if (formData.maxDeployMent == null || formData.maxDeployMent <= 0 || formData.maxDeployMent > 2000) {
        this.$message.error('请正确填写maxDeployMent，范围[1,2000]');
        return;
      }
      if (formData.parallelNum == null || formData.parallelNum <= 0 || formData.parallelNum > 2000) {
        this.$message.error('请正确填写parallelNum，范围[1,2000]');
        return;
      }
      if (formData.parallelPostion == null || formData.parallelPostion < 0 || formData.parallelPostion > 2000) {
        this.$message.error('请正确填写parallelPostion');
        return;
      }
      if (formData.destinationVRadio == null || formData.destinationVRadio <= 0) {
        this.$message.error('请正确填写destinationVRadio');
        return;
      }
      this.loading=true;
      // 根据情况调用算法
      switch (this.alType) {
        case 1:
          this.createNetGraph();
          break;
        case 2:
          this.createCAGraph();
          break;
      }
    },
    /**
     * 生成图表
     */
    createNetGraph() {
      this.getBMPE(1).then((ret) => {
        this.loading=false;
        this.centerDialogVisible=false;
            if (ret.status !== 200) {
              this.$message.error("服务器内部异常！");
              return null;
            }
            if (ret.data.status !== 200) {
              this.$message.error("server error:"+ret.data.data);
              return null;
            }

            let retData = ret.data.data;
            let nextData = ret.data.data;
            let sourcePoint = ret.data.data.request.source;
            let graph = retData.graph;
            // 服务器节点
            let serverPoint = retData.functionV;
            let pointAll = graph.graph_V;
            let showNetNodes = [];
            for (let i in pointAll) {
              let temp = {
                "id": i,
                "label": i,
                "group": 1,
                size: 16,
                color: {
                  border: '#2B7CE9',
                  background: '#97C2FC',
                  highlight: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  },
                  hover: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  }
                },
              }
              if (serverPoint.includes(Number(i))) {
                // 不知道为什么没效果...被全局覆盖了？
                temp["group"] = 2;
                temp["color"] = "#c75450";
              }
              // 如果是源节点
              if (Number(sourcePoint) == Number(i)) {
                temp["group"] = 3;
              }
              showNetNodes.push(temp)
            }
            let edgeAll = graph.graph_E;
            let showEdege = [];
            for (let i = 0; i < edgeAll.length; i++) {
              for (let j = i; j < edgeAll[i].length; j++) {
                if (Number(edgeAll[i][j]) != 0 && Number(edgeAll[i][j]) != MAX) {
                  let tempEdge = {
                    from: i, to: j,
                    color: '#2B7CE9'
                  }
                  showEdege.push(
                      tempEdge
                  );
                }
              }
            }
            networkNodes = new vis.DataSet(showNetNodes);
            networkEdges = new vis.DataSet(showEdege);
            let container = document.getElementById("mynetwork");
            let data = {
              nodes: networkNodes,
              edges: networkEdges
            };
            // 操作配置
            let options = {};
            new vis.Network(container, data, options);
            // 保存到表格
            let tableShow = {
              "num": Number(this.tableData.length) + 1,
              "alType": this.alType == 1 ? "NAC" : "CA",
              "weightsum": retData.ncaResult.weightsum,
              "deployServer": this.dealDeployNode(retData.ncaResult.deployServer, ","),
              "deployNode": this.dealDeployNode(retData.ncaResult.deployNode, ",")
            }
            this.tableData.push(tableShow);
            this.initGraphResult(nextData);
            return null;
          }
      )
    },
    /**
     * 把数组处理成->
     * @param deployNode
     */
    dealDeployNode(deployNode, spiltString) {

      let retString = null;
      for (let i = 0; i < deployNode.length; i++) {
        if (retString != null) {
          retString += spiltString;
        }
        retString += deployNode[i];

      }
      return retString;
    },
    createCAGraph() {
      this.getBMPE(2).then((ret) => {
        this.loading=false;
        this.centerDialogVisible=false;
            if (ret.status !== 200) {
              this.$message.error("服务器内部异常！");
              return null;
            }
            if (ret.data.status !== 200) {
              this.$message.error("server error:"+ret.data.data);
              return null;
            }
            let retData = ret.data.data;
            let nextData = ret.data.data;
            let sourcePoint = ret.data.data.request.source;
            let graph = retData.graph;
            // 服务器节点
            let serverPoint = retData.functionV;
            let pointAll = graph.graph_V;
            let showNetNodes = [];
            for (let i in pointAll) {
              let temp = {
                "id": i,
                "label": i,
                "group": 1,
                size: 16,
                color: {
                  border: '#2B7CE9',
                  background: '#97C2FC',
                  highlight: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  },
                  hover: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  }
                },
              }
              if (serverPoint.includes(Number(i))) {
                // 不知道为什么没效果...被全局覆盖了？
                temp["group"] = 2;
                temp["color"] = "#c75450";
              }
              // 如果是源节点
              if (Number(sourcePoint) == Number(i)) {
                temp["group"] = 3;
              }
              showNetNodes.push(temp)
            }
            let edgeAll = graph.graph_E;
            let showEdege = [];
            for (let i = 0; i < edgeAll.length; i++) {
              for (let j = i; j < edgeAll[i].length; j++) {
                if (Number(edgeAll[i][j]) != 0 && Number(edgeAll[i][j]) != MAX) {
                  let tempEdge = {
                    from: i, to: j,
                    color: '#2B7CE9'
                  }
                  showEdege.push(
                      tempEdge
                  );
                }
              }
            }
            networkNodes = new vis.DataSet(showNetNodes);
            networkEdges = new vis.DataSet(showEdege);
            let container = document.getElementById("mynetwork");
            let data = {
              nodes: networkNodes,
              edges: networkEdges
            };
            // 操作配置
            let options = {};
            new vis.Network(container, data, options);
            // 保存到表格
            let tableShow = {
              "num": Number(this.tableData.length) + 1,
              "alType": this.alType == 1 ? "NAC" : "CA",
              "weightsum": retData.ncaResult.weightsum,
              "deployServer": this.dealDeployNode(retData.ncaResult.deployServer, ","),
              "deployNode": this.dealDeployNode(retData.ncaResult.deployNode, ",")
            }
            this.tableData.push(tableShow);
            this.initGraphResult(nextData);
            return null;
          }
      )
    },
    /**
     * 结果图显示
     */
    initEcharts() {
      // 找不到设备的长和宽
      Object.defineProperty(document.getElementById('emain'), 'clientWidth', {
        get: function () {
          return 600;
        }
      })
      Object.defineProperty(document.getElementById('emain'), 'clientHeight', {
        get: function () {
          return 540;
        }
      })
      echarts.use([GridComponent, BarChart, CanvasRenderer]);
      let chartDom = document.getElementById('emain');
      this.mycharts = this.$echarts.init(chartDom);
      this.loadTable();
    }
    ,
    loadTable() {
      let option;
      option = {
        xAxis: this.xAxis,
        yAxis: {
          type: 'value'
        },
        series: this.series
      };
      this.mycharts.setOption(option);
    }
    ,
    /**
     * 随机添加节点
     */
    radomPoint() {
      console.log("点击生成点");
      let length = networkNodes.length;
      let newPoint = {
        id: length + 1,
        label: "Node " + length
      };
      let line = {from: 1, to: length + 1};
      networkNodes.add(newPoint);
      networkEdges.add(line);
    }
    ,
    /**
     * 随机生成结果
     */
    redomResult() {
      let time = Math.floor(Math.random() * 200 + 1);
      let money = Math.floor(Math.random() * 200 + 1);
      let value = [];
      value.push(time);
      value.push(money);
      console.log(value);
      this.series[0].data = value;
      this.loadTable();
    }
    ,
    getBMPE(requestType) {
      // 默认的一些参数
      let requestMap = this.form;
      if (requestType === 1) {
        // 使用bmpe算法
        return GetBMPE(requestMap);
      } else {
        return GetCA(requestMap);
      }
    },
    /***
     * 右边渲染结果树
     * @param res
     */
    async initGraphResult(res) {
      let resultTree = res.ncaResult.resultTree;
      let limitLength = res.graph.graph_V.length;
      console.log("长度：" + limitLength);
      let sourcePoint = res.request.source;
      console.log("源点：" + sourcePoint);
      let showEdges = [];
      let showNodes = [];
      // 服务器节点
      let serverPoint = res.functionV;
      console.log("服务器节点：" + serverPoint);
      let map = {};
      for (let i = 0; i < limitLength; i++) {
        for (let j = 0; j < i; j++) {
          if (Number(resultTree[i][j]) != 0) {
            // 添加边
            let tempEdge = {
              from: i,
              to: j,
              color: '#2B7CE9'
            }
            showEdges.push(
                tempEdge
            );
            // 存在点，连接,添加点，添加边
            if (map[i] == null || map[i] == undefined) {
              map[i] = true;
              let temp = {
                "id": i,
                "label": String(i),
                "group": 1,
                size: 16,
                color: {
                  border: '#2B7CE9',
                  background: '#97C2FC',
                  highlight: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  },
                  hover: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  }
                },
              }

              if (serverPoint.includes(Number(i))) {
                // 不知道为什么没效果...被全局覆盖了？
                temp["group"] = 2;
                temp["color"] = {
                  border: "#ffe793",
                  background: "#c75450",
                  highlight: {
                    border: '#ffe793',
                    background: '#c75450'
                  },
                  hover: {
                    border: '#ffe793',
                    background: '#c75450'
                  }
                }
                console.log("存在服务器中：" + i);
              }
              if (String(sourcePoint) == String(i)) {
                temp["group"] = 3;
              }
              showNodes.push(temp)
            }
            // 存在点，连接,添加点，添加边
            if (map[j] == null || map[j] == undefined) {
              map[j] = true;
              let secondTemp = {
                "id": j,
                "label": String(j),
                "group": 1,
                size: 16,
                color: {
                  border: '#2B7CE9',
                  background: '#97C2FC',
                  highlight: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  },
                  hover: {
                    border: '#2B7CE9',
                    background: '#D2E5FF'
                  }
                },
              }

              if (serverPoint.includes(Number(j))) {
                // 不知道为什么没效果...被全局覆盖了？
                secondTemp["group"] = 2;
                secondTemp.color = {
                  border: '#ffe793',
                  background: '#c75450',
                  highlight: {
                    border: '#ffe793',
                    background: '#c75450'
                  },
                  hover: {
                    border: '#ffe793',
                    background: '#c75450'
                  }
                }
                console.log("存在服务器中：" + j);
              }
              if (String(sourcePoint) == String(j)) {
                secondTemp["group"] = 3;
              }
              showNodes.push(secondTemp)
            }


          }
        }
      }
      // console.log(showEdges);
      // console.log(showNodes);
      netResultNodes = new vis.DataSet(showNodes);
      // create an array with edges
      // networkEdges = new vis.DataSet(this.tempNetworkEdges);
      netResultEdges = new vis.DataSet(showEdges);
      let container = document.getElementById("mynetworkRoute");
      let data = {
        nodes: netResultNodes,
        edges: netResultEdges
      };
      // 操作配置
      let options = {};
      new vis.Network(container, data, options);
    }
  },
  components: {}
}
</script>
<style>
.text {
  font-size: 14px;
}

.item {
  padding: 18px 0;
}

/**body 样式**/
.el-card__body {
  height: 100%;
}


.box-card-left {
  /*display: flex;*/
  margin-top: 3%;
  margin-left: 3%;
  width: 45%;
  /*// 这里直接写死*/
  height: 700px;
  /*height: 100%;*/
}

.box-card-right {
  /*display: flex;*/
  margin-top: 3%;
  margin-left: 3%;
  width: 45%;
  /*height: 500px;*/
  /*height: 100%;*/
  height: 700px;
}

.table-button {
  margin: auto;
  margin-top: 3%;
  /*margin-left: 15%;*/
  /*margin-right: 15%;*/
  width: 50%;
}

/*拓扑图显示*/
#mynetwork {
  width: 100%;
  height: 100%;
  /*border: 1px solid lightgray;*/
}

#mynetworkRoute {
  width: 100%;
  height: 100%;
}

.el-input {

  width: 120px;

}
</style>
